package com.user.mediacoderdemo;

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.Build;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;


class WorkThread implements Runnable {

    private static final String TAG = "zoudong";
    String path;
    String mp3;
    private int framerate;

    public WorkThread(String path, String mp3) {
        this.path = path;
        this.mp3 = mp3;
    }

    public WorkThread(String path) {
        this.path = path;
    }

    @Override
    public void run() {
        //Android提供了一个extractor类，可以用来分离容器中的视频track和音频track
        MediaExtractor extractor = new MediaExtractor();
        MediaExtractor mAudioExtractor = new MediaExtractor();
        String mOutputVideoPath = new File(path).getParent() + File.separator + SystemClock.currentThreadTimeMillis() + "output.mp4";
        MediaMuxer mediaMuxer = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            try {
                mediaMuxer = new MediaMuxer(mOutputVideoPath,
                        MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            if (!TextUtils.isEmpty(path)) {
                extractor.setDataSource(path);
            }
            if (!TextUtils.isEmpty(mp3)) {
                mAudioExtractor.setDataSource(mp3);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        int videoTrackIndex = -1;
        int audioTrackIndex = -1;
        videoTrackIndex = getVideoTrackIndex(extractor, mediaMuxer);
        audioTrackIndex = getAudioTrackIndex(mAudioExtractor, mediaMuxer);
        if (-1 == videoTrackIndex) {
            return;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            mediaMuxer.start();   // 添加完所有轨道后start
        }

        optitionVideo(extractor, mediaMuxer, videoTrackIndex);


        if (-1 == audioTrackIndex) {
            return;
        }
        optitionmp3(mAudioExtractor, mediaMuxer, audioTrackIndex);

        // 释放extractor
        extractor.release();
        mAudioExtractor.release();
        // 释放MediaMuxer
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            //没有调用start 出现 异常  java.lang.IllegalStateException: Can't stop due to wrong state
            mediaMuxer.stop();
            mediaMuxer.release();
        }

    }

    private int getAudioTrackIndex(MediaExtractor mAudioExtractor, MediaMuxer mediaMuxer) {
        int audioTrackIndex = -1;
        int mp3trackCount = mAudioExtractor.getTrackCount();
        Log.e(TAG, "audio-------trackCount: " + mp3trackCount);
        for (int i = 0; i < mp3trackCount; i++) {
            MediaFormat format = mAudioExtractor.getTrackFormat(i);   //音频只有  sample-rate  没有 frame_rate
            if (format.getString(MediaFormat.KEY_MIME).startsWith("audio/")) {
                Log.d(TAG, "audio --->MediaFormat==="+format.toString());
                Log.d(TAG, "1-extractor.getSampleTrackIndex():" + mAudioExtractor.getSampleTrackIndex());
                 mAudioExtractor.selectTrack(i);
                Log.d(TAG, "2-extractor.getSampleTrackIndex():" + mAudioExtractor.getSampleTrackIndex());
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                    audioTrackIndex = mediaMuxer.addTrack(format);
                }
            }
        }
        return audioTrackIndex;
    }

    private int getVideoTrackIndex(MediaExtractor extractor, MediaMuxer mediaMuxer) {
        int trackCount = extractor.getTrackCount(); //轨道数
        Log.d(TAG, "video--------trackCount: " + trackCount);
        int videoTrackIndex = -1;
        for (int i = 0; i < trackCount; i++) {
            MediaFormat trackFormat = extractor.getTrackFormat(i);
            if (trackFormat.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
                 Log.d("zoudong", "video --->MediaFormat==="+trackFormat.toString());
                framerate = trackFormat.getInteger(MediaFormat.KEY_FRAME_RATE);
                Log.d(TAG, "1-extractor.getSampleTrackIndex():" + extractor.getSampleTrackIndex());
                extractor.selectTrack(i);
                Log.d(TAG, "2-extractor.getSampleTrackIndex():" + extractor.getSampleTrackIndex());
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                    videoTrackIndex = mediaMuxer.addTrack(trackFormat);
                }
            }
        }
        return videoTrackIndex;
    }

    @SuppressWarnings("ResourceType")
    private void optitionmp3(MediaExtractor extractor, MediaMuxer mediaMuxer, int audioTrackIndex) {
        // 封装音频track   Unsupported mime 'audio/mpeg'   不支持 mp3
        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        info.presentationTimeUs = 0;
        int trackIndex = extractor.getSampleTrackIndex();
        ByteBuffer audiobuffer = ByteBuffer.allocate(extractor.getTrackFormat(trackIndex).getInteger(MediaFormat.KEY_MAX_INPUT_SIZE));
        while (true) {
            int sampleSize = extractor.readSampleData(audiobuffer, 0);
            if (sampleSize < 0) {
                //这里一定要释放选择的轨道，不然另一个轨道就无法选中了
                extractor.unselectTrack(trackIndex);
                break;
            }

            //获取时间戳
            long presentationTimeUs = extractor.getSampleTime();
            //获取帧类型，只能识别是否为I帧
            int sampleFlag = extractor.getSampleFlags();

//            Log.d(TAG, "mp3---->trackIndex is " + trackIndex
//                    + ";presentationTimeUs is " + presentationTimeUs
//                    + ";sampleFlag is " + sampleFlag
//                    + ";sampleSize is " + sampleSize);
            extractor.advance();
            info.offset = 0;
            info.size = sampleSize;
            info.flags = sampleFlag;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                mediaMuxer.writeSampleData(audioTrackIndex, audiobuffer, info);
            }
            info.presentationTimeUs = extractor.getSampleTime();  //
        }
    }

    @SuppressWarnings("ResourceType")
    private void optitionVideo(MediaExtractor extractor, MediaMuxer mediaMuxer, int videoTrackIndex) {
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        bufferInfo.presentationTimeUs = 0;
        int trackIndex = extractor.getSampleTrackIndex();
        ByteBuffer buffer = ByteBuffer.allocate(extractor.getTrackFormat(trackIndex).getInteger(MediaFormat.KEY_MAX_INPUT_SIZE));
        while (true) {
            int sampleData = extractor.readSampleData(buffer, 0);
            if (sampleData < 0) {
                //这里一定要释放选择的轨道，不然另一个轨道就无法选中了
                extractor.unselectTrack(trackIndex);
                break;
            }

            //获取时间戳
            long presentationTimeUs = extractor.getSampleTime();
            //获取帧类型，只能识别是否为I帧
            int sampleFlag = extractor.getSampleFlags();

//            Log.d(TAG, "trackIndex is " + trackIndex
//                    + ";presentationTimeUs is " + presentationTimeUs
//                    + ";sampleFlag is " + sampleFlag
//                    + ";sampleSize is " + sampleData);
            extractor.advance();
            bufferInfo.offset = 0;
            bufferInfo.size = sampleData;
            bufferInfo.flags = sampleFlag;
//          bufferInfo.presentationTimeUs += 1000 * 1000 / framerate;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                mediaMuxer.writeSampleData(videoTrackIndex, buffer, bufferInfo);
            }
            bufferInfo.presentationTimeUs = extractor.getSampleTime();  //
//          bufferInfo.presentationTimeUs += 1000 * 1000 / framerate;//presentationTimeUs;

        }
    }

}